﻿using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using DBEntitie;
using Microsoft.AspNetCore.DataProtection;
using Microsoft.Extensions.Caching.Redis;
using Microsoft.Extensions.DependencyInjection;
using StackExchange.Redis;


namespace FrameWork
{
   public class RedisCacheService
   {
        private static IDatabase _cache;

        private static string _instance;

       public static void Init(IServiceCollection services)
       {
            var redisConn = ConfigurationManager.AppSettings("RedisConnection");
            var redisInstanceName = ConfigurationManager.AppSettings("RedisInstanceName");
            var connection = ConnectionMultiplexer.Connect(redisConn);
            services.AddDataProtection().PersistKeysToRedis(connection, "RedisDataProtection");

            var redisCacheOptions = new RedisCacheOptions
            {
                Configuration = redisConn,
                InstanceName = redisInstanceName
            };

            services.AddDistributedRedisCache(option =>
            {
                option.Configuration = redisCacheOptions.Configuration;
                option.InstanceName = redisCacheOptions.InstanceName;
            });

            _cache = connection.GetDatabase(1);
            _instance = redisCacheOptions.InstanceName;
        }

       public static object GetCacheValue(string key)
       {
            if (string.IsNullOrWhiteSpace(key)) return null;

            var value = _cache.StringGet(GetKeyForRedis(key));

            if (!value.HasValue) return null;

            using (var ms = new MemoryStream(value))
            {
                return new BinaryFormatter().Deserialize(ms);
            }
        }

       public static void SetChacheValue(string key, object value, int hours = 0)
       {
            if (string.IsNullOrWhiteSpace(key)) return;

            using (var ms = new MemoryStream())
            {
                new BinaryFormatter().Serialize(ms, value);

                if (hours.Equals(0))
                {
                    _cache.StringSet(GetKeyForRedis(key), ms.GetBuffer());
                }
                else
                {
                    _cache.StringSet(GetKeyForRedis(key), ms.GetBuffer(), TimeSpan.FromHours(hours));
                }
            }
        }

       public static void RemoveChacheValue(string key)
       {
            if (string.IsNullOrWhiteSpace(key)) return;

            _cache.KeyDelete(GetKeyForRedis(key));
        }
        private static string GetKeyForRedis(string key)
        {
            return _instance + "." + key;
        }
    }
}
